<?php
// +----------------------------------------------------------------------
// | YBlog
// +----------------------------------------------------------------------
// | Copyright (c) 2008 http://www.yhustc.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: yhustc <yhustc@gmail.com>
// +----------------------------------------------------------------------
// $Id$

/**
 +------------------------------------------------------------------------------
 * YBlog日志管理模块
 +------------------------------------------------------------------------------
 * @author    yhustc <yhustc@gmail.com>
 * @version   $Id$
 +------------------------------------------------------------------------------
 */


class BlogAction extends BaseAction
{
	/**
     +----------------------------------------------------------
     * 日志列表
     +----------------------------------------------------------
     * @access public 
     +----------------------------------------------------------
     */
	function index()
	{
		$postsDao = D("PostsView");
		
		$where = array();
		$post_type = empty($_GET["type"])?"post":$_GET["type"];
		$where["post_type"] = $post_type; //只取日志,页面不做列表,只做单独的页面显示
		if(isset($_GET["filter"]))
		{
			switch($_GET["filter"])
			{
				case "category": $where["slug"] = $_GET["v"];
					$this->assign("selectSlug",$_GET["v"]);
					break;
				case "archive": $nextFirstDay = date('Y-m-01 00:00:00',strtotime('+1 month',strtotime($_GET["v"])));
					$where["post_date"] = array(array("egt",$_GET["v"]."-01 00:00:00"),array("lt",$nextFirstDay),"AND"); //本月1号开始到下个月1号结束
					$this->assign("selectArchive",$_GET["v"]);
					break;
				default:
					break;
			}
		}
		
		$total = $postsDao->count($where);
		import("ORG.Util.Page");
		$page = new Page($total,20);
		$postList = $postsDao->where($where)->order("post_date desc")->limit($page->firstRow.",".$page->listRows)->findAll();
		
		/*获取日志分类*/
		$categoryDao = D("Category");
		$rs = $categoryDao->field("`slug`,`name`")->findAll();
		$categoryList = $categoryDao->getCols($rs,"slug,name");
		$this->assign("categoryList",$categoryList);

		/*获取日志归档*/
		$archiveDao = new Model();
		$sql = "SELECT DISTINCT EXTRACT( YEAR_MONTH FROM `post_date` ) AS AddYearMonth FROM `".C("DB_PREFIX")."posts` ORDER BY AddYearMonth DESC";
		$archives = $archiveDao->query($sql);
		$archiveList = array();
		foreach($archives as $value)
			$archiveList[substr($value["AddYearMonth"],0,4)."-".substr($value["AddYearMonth"],4)] = substr($value["AddYearMonth"],0,4)."年".substr($value["AddYearMonth"],4)."月";
		
		/*类型(post or page)*/
		$typeList = array("post"=>"日志","page"=>"页面");
		$this->assign("typeList",$typeList);
		$this->assign("selectType",$post_type);

		$this->assign("pageFile","Blog:index");
		$this->assign("postList",$postList);
		$this->assign("archiveList",$archiveList);
		$this->assign("navigation",$page->show());
		$this->layout();
	}
	
	/**
     +----------------------------------------------------------
     * 发布/修改 日志/页面
     +----------------------------------------------------------
     * @access public 
     +----------------------------------------------------------
     */
	function post()
	{
		if((isset($_GET["ID"]) && !empty($_GET["ID"])) || (isset($_POST["field"]) && !empty($_POST["fieldValue"])))
		{
			$postDao = D("Posts");
			$postVo = "";
			if(isset($_GET["ID"]))
				$postVo = $postDao->xfind($_GET["ID"]);
			else
				$postVo = $postDao->xfind($_POST["field"]."='".$_POST["fieldValue"]."'");
			
			//附件列表
			$attachList = array();
			foreach($postVo["attachList"] as $attach)
			{
				$attachJS = D("Attach")->parseAttach($this->options,$attach);
				$attachList[] = $attachJS;
			}

			//根据日志ID获取tags			
			$where = array();
			$where["postid"] = $postVo["ID"];
			$tagDao = D("Tags");
			$tagResult = $tagDao->findAll($where);
			$tags = "";
			foreach($tagResult as $tag)		
				$tags .= $tag["tag_name"].",";
			
			$this->assign("postAction","修改日志");
			$this->assign("post",$postVo);
			$this->assign("tags",rtrim($tags,","));
			$this->assign("attachList",$attachList);
		}
		else
			$this->assign("postAction","写新日志");

		/*日志分类列表*/
		$categoryDao = D("Category");
		$rs = $categoryDao->field("`cid`,`name`")->findAll();
		$categoryList = $categoryDao->getCols($rs,"cid,name");
		$this->assign("categoryList",$categoryList);

		/*日志状态*/
		$typeList = array("post"=>"日志","page"=>"页面");
		$post_statusList = array("publish"=>"发布","draft"=>"草稿");
		$topList = array("0"=>"否","1"=>"是");
		$statusList = array("open"=>"允许","closed"=>"不允许");

		$this->assign("selectCid",empty($postVo["post_category"])?$this->options["default_category"]:$postVo["post_category"]);
		$this->assign("typeList",$typeList);
		$this->assign("post_statusList",$post_statusList);
		$this->assign("topList",$topList);
		$this->assign("statusList",$statusList);
		$this->assign("selectType",$postVo["post_type"]);
		$this->assign("selectPost_status",$postVo["post_status"]);
		$this->assign("selectTop",$postVo["top"]);
		$this->assign("selectComment_status",empty($postVo["comment_status"])?$this->options["default_comment_status"]:$postVo["comment_status"]);
		$this->assign("selectPing_status",empty($postVo["ping_status"])?$this->options["default_ping_status"]:$postVo["ping_status"]);

		$this->assign("pageFile","Blog:post");		
		$this->layout();
	}
	
	/**
     +----------------------------------------------------------
     * 保存日志
     +----------------------------------------------------------
     * @access public 
     +----------------------------------------------------------
     */
	function save()
	{
		$postDao = D("Posts");

		if(empty($_POST["post_name"]) && $this->options['auto_post_name'] == "true") // 没有设置短标题,且配置为需要自动用google翻译一个
			$_POST["post_name"] = translateByGoogle($_POST["post_title"]);

		$vo = $postDao->create();
		if(!$vo)
			$this->error($postDao->getError());

		$rs = false;
		$sqlType = "";
		$success = "";
		$error = "";
		if(!empty($_POST["ID"]))
		{
			$rs = $postDao->save();
			$sqlType = "update";
			$success = "修改内容成功";
			$error = "修改内容失败";
		}
		else
		{
			$rs = $postDao->add();
			$sqlType = "insert";
			$success = "添加内容成功";
			$error = "添加内容失败";
		}

		if($rs)
		{
			//如果是insert，日志的ID就是$rs，否则取$_POST["ID"]
			$postId = empty($_POST["ID"])?$rs:$_POST["ID"];
			
			/*把附件表里相关附件的postId设置为这篇日志的ID*/
			if(isset($_POST["attachId"]) && count($_POST["attachId"])>0)
			{
				$attachIds = implode(",",$_POST["attachId"]);
				$attachDao = D("Attach");
				$attachDao->setField("postId",$postId,"id IN (".$attachIds.")");
				//判断附件是否插入到文章里了
				$insertIds = array();
				foreach($_POST["insertFile"] as $key=>$value)
				{
					if(strstr($_POST["post_content"],str_replace("&","&amp;",$value)))
						$insertIds[] = $_POST["attachId"][$key];
				}
				$attachDao->setField("inserted","0","id IN (".$attachIds.")");
				$attachDao->setField("inserted","1","id IN (".implode(",",$insertIds).")");
			}
			/*更新TAG*/
			$tagDao = D("Tags");
			$tagDao->delete("postid='".$postId."'"); //把这篇日志以前的TAG全删除
			//添加新的TAG
			if(!empty($_POST["tags"]))
			{
				$data = array();
				$tagArray = explode(",",$_POST["tags"]);
				//这里可能存在一些无效的东西,比如两个连续的,,或者前后有空格
				foreach($tagArray as $tag)
				{
					$tag = trim($tag);
					if(!empty($tag))
						$data[] = array("postid"=>$postId, "tag_name"=>$tag);
				}						
				$tagDao->addAll($data); //批量写入
			}
			
			/*设置分类计数*/
			$categoryDao = D("Category");
			if($sqlType == "insert" && $_POST["post_type"]=='post') //页面不计入分类中
				$categoryDao->setInc("`count`","cid='".$_POST["post_category"]."'");
			else if($sqlType == "update" && $_POST["post_category"] != $_POST["pre_category"])
			{ //一般在页面与日志之间变的情况比较少,这里就不考虑了
				//update,且改变了分类,需要修改一下分类的日志计数
				$categoryDao->setDec("`count`","cid='".$_POST["pre_category"]."'");
				$categoryDao->setInc("`count`","cid='".$_POST["post_category"]."'");
			}
			
			//发送引用通告,这里如果有多个地址,可能会比较费时间
			if(!empty($_POST["trackbackUrl"]) && !strstr(get_cfg_var('disable_functions'),'fsockopen'))
			{
				$trackbacks = explode(";",$_POST["trackbackUrl"]);
				foreach($trackbacks as $trackback)
					$this->sendTrackBack(trim($trackback),$postId,$_POST["post_title"],$_POST["post_content"],$this->options["blogname"]);	
			}
			
			//由于日志计数不是必须的,且后台可一键修复,他的错误不是致命的,所以不对执行结果进行判断
			if($this->isAjax()) //主要是要返回一个id给前台使用,所以放须用ajaxReturn
				$this->ajaxReturn($postId,'自动保存内容成功',1);
			else
				$this->success($success);
		}
		else
			$this->error($error);
	}
	
	/**
     +----------------------------------------------------------
     * 对日志发出引用通告
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @param string $trackback  引用通告的发送地址
     * @param string $ID  本日志的ID,用于构造回访的URL
     * @param string $title  本日志的标题
     * @param string $content  本日志的内容摘要
     * @param string $blogname  本博客的标题
     +----------------------------------------------------------
     * @return void
     +----------------------------------------------------------
     */
	function sendTrackBack($trackback,$ID,$title,$content,$blogname)
	{
		$host = "";
		if(preg_match('/^http:\/\/(.*?)\//',$trackback,$regs))
		//$trackback肯定会带文件名部分,所以hostname后面肯定会带一个/
			$host = $regs[1];
		else
			return ;
		
		$fp = fsockopen($host,80,$errno,$errstr,10);
		//因为可能一次发送多个trackback,所以每一个只给10秒超时
		if(!$fp)
			return ;
		
		$value = "url=".$this->options["siteurl"]."/index.php?s=/Blog/".$ID."&blog_name=".$blogname."&title=".$title."&excerpt=".msubstr(preg_replace('/<\\/*[^<>]*>/',"",nl2br($content)),0,80); //引用通告正文最多252个字符,UTF-8保守估计全是汉字,每个三字节,取80
		$request = "POST ".$trackback." HTTP/1.1\r\nAccept: text/xml\r\nAccept-Language: zh-cn\r\nContent-Type: application/x-www-form-urlencoded\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)\r\nHost: ".$host."\r\nContent-Length: ".strlen($value)."\r\nConnection: Keep-Alive\r\nCache-Control: no-cache\r\n\r\n".$value;
		fputs($fp, $request);
		
		//下面开始接收返回的xml
		//但是这个结果其实又不会返回给用户看,所以不管<error>*</error>里面是什么,先不管了
		$contentLength = 1024;
		while (!feof($fp)) {
	        $response = fgets($fp, 1024);
	        $response = str_replace(array("\r","\n"),"",$response);
	        if(empty($response)) //读到空行,response头部结束
	        	break;
	        
	        if (preg_match('/Content-Length: (\\d+)/i', $response, $regs))
				$contentLength = $regs[1];
	    }
	    fgets($fp,$contentLength); //使用Content-Length指示的大小读正文内容
	    fclose($fp);
	}
	
	/**
     +----------------------------------------------------------
     * 删除日志
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     */
	function del()
	{
		$postDao = D("Posts");
		$tagDao = D("Tags");
		$commentDao = D("Comments");

		if(isset($_POST["ID"]) && is_array($_POST["ID"]))
			$ids = implode(",",$_POST["ID"]);
		else if(isset($_GET["ID"]) && !empty($_GET["ID"]))
			$ids = $_GET["ID"];
		else
			$this->error("请求的参数不正确！");

		$postDao->delete($ids);

		//删除了多条记录的话,直接使用SQL重新统计一下各个分类的日志数目
		$Dao = new Model();
		$Dao->execute("UPDATE `".C("DB_PREFIX")."category` SET `count` = ( SELECT COUNT( `ID` ) FROM `".C("DB_PREFIX")."posts` WHERE `".C("DB_PREFIX")."posts`.`post_category` = `".C("DB_PREFIX")."category`.`cid` ) ");
		
		/*删除相关TAG记录*/
		$tagDao->deleteBy('postid',array("IN",$ids));
		/*删除相关的评论*/
		$commentDao->deleteBy('comment_post_ID',array("IN",$ids));

		$this->success("删除日志成功");
	}
} 
?>